package com.xls.commonlibrary.util;

import static com.xls.commonlibrary.constant.Const.USER_GAME_INFO;
import static com.xls.commonlibrary.util.eventbus.ConstEventBus.EVENT_LOGIN_DISSMISS_DIALOG;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;

import com.orhanobut.logger.Logger;
import com.xls.commonlibrary.app.MainApplication;
import com.xls.commonlibrary.bean.UserGameInfo;
import com.xls.commonlibrary.http.CallbackT;
import com.xls.commonlibrary.http.Transformer;
import com.xls.commonlibrary.util.cache.ACache;
import com.xls.commonlibrary.util.eventbus.MessageEvent;

import org.greenrobot.eventbus.EventBus;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Nonnull;

import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableEmitter;
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;

public class LoginUtil {
    private static volatile LoginUtil singleton = null;

    private LoginUtil() {
    }

    public static LoginUtil getInstance() {
        if (singleton == null) {
            synchronized (LoginUtil.class) {
                if (singleton == null) {
                    singleton = new LoginUtil();
                }
            }
        }
        return singleton;
    }


    @SuppressLint("CheckResult")
    public void getLoginParams(Activity activity, CallbackT<Map<String, String>> callback) {
        // rxjava contactArray 合并 同步和异步的事件后，最终调用接口

        // 必须有序拼接，才能明确，拼接完成的事件
        // TToast.show(activity, "uploadInfo");
        Observable<Map<String, String>> observableSystem = Observable.create(new ObservableOnSubscribe<Map<String, String>>() {
            @Override
            public void subscribe(@io.reactivex.rxjava3.annotations.NonNull ObservableEmitter<Map<String, String>> emitter) throws Throwable {
                Map<String, String> params = new HashMap<>();
                params.putAll(SysDataUtil.getInstance().getLoginInfo(activity));

                emitter.onNext(params);
                //    必须通知
                emitter.onComplete();
            }
        });

        Observable<Map<String, String>> observablePicture = Observable.create(new ObservableOnSubscribe<Map<String, String>>() {
            @Override
            public void subscribe(@io.reactivex.rxjava3.annotations.NonNull ObservableEmitter<Map<String, String>> emitter) throws Throwable {
                SysDataUtil.getInstance().getPictureSum(activity, new CallbackInt() {
                    @Override
                    public void callback(int num) {

                        Map<String, String> params = new HashMap<>();
                        params.put("photos", num + "");

                        emitter.onNext(params);

                        //    必须通知
                        emitter.onComplete();
                    }
                });
            }
        });

        // 组合参数
        Map<String, String> params = new HashMap<>();

        // merge 是无序的
        Observable.concat(observableSystem, observablePicture)
                .compose(Transformer.transform())
//                .doOnNext()
//                .doOnComplete()
                .subscribe(new Observer<Map<String, String>>() {
                    // subscribe 结束流的标志，没有后续的操作了
                    @Override
                    public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@io.reactivex.rxjava3.annotations.NonNull Map<String, String> map) {
                        params.putAll(map);
                        // 执行多次
                        Logger.d("params: " + params.size());
                    }

                    @Override
                    public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
//                        获取风控参数失败，取消登陆  销毁登陆弹窗
                        EventBus.getDefault().post(new MessageEvent(EVENT_LOGIN_DISSMISS_DIALOG, ""));
                    }

                    @Override
                    public void onComplete() {
                        // concat 事件 完成 后调用 也就是异步获取参数拼接完成后执行
                        // onComplete 执行一次还行

                        params.put("source_old", "game_login");
                        params.put("source", "game_login");
                        Logger.d("login params:" + params.size());
                        Logger.d("login params:" + params);

                        if (callback != null) callback.callback(params);
                    }
                });

        // flatMap + doOnNext后， 还可以拼接 其他类型Observavle
        // 这里可以直接加上调用接口的Observavle,形成链式调用,hook不符合rxjva的精髓


    }

    public void getLoginParams2(Activity activity, CallbackT<Map<String, String>> callback) {
        // rxjava contactArray 合并 同步和异步的事件后，最终调用接口
        // 必须有序拼接，才能明确，拼接完成的事件
        Observable<Map<String, String>> observableSystem = Observable.create(new ObservableOnSubscribe<Map<String, String>>() {
            @Override
            public void subscribe(@io.reactivex.rxjava3.annotations.NonNull ObservableEmitter<Map<String, String>> emitter) throws Throwable {
                Map<String, String> params = new HashMap<>();
                params.putAll(SysDataUtil.getInstance().getLoginInfo2(activity));
                emitter.onNext(params);
                //    必须通知
                emitter.onComplete();
            }
        }).subscribeOn(Schedulers.io());

        Observable<Map<String, String>> observablePicture = Observable.create(new ObservableOnSubscribe<Map<String, String>>() {
            @Override
            public void subscribe(@io.reactivex.rxjava3.annotations.NonNull ObservableEmitter<Map<String, String>> emitter) throws Throwable {
                SysDataUtil.getInstance().getPictureSum(activity, new CallbackInt() {
                    @Override
                    public void callback(int num) {
                        Map<String, String> params = new HashMap<>();
                        params.put("photos", num + "");
                        emitter.onNext(params);
                        //    必须通知
                        emitter.onComplete();
                    }
                });
            }
        }).subscribeOn(Schedulers.io());

        // 组合参数
        Map<String, String> params = new HashMap<>();
        // merge 是无序的
        Observable.concat(observableSystem, observablePicture)
                .compose(Transformer.transform())
//                .doOnNext()
//                .doOnComplete()
                .subscribe(new Observer<Map<String, String>>() {
                    // subscribe 结束流的标志，没有后续的操作了
                    @Override
                    public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@io.reactivex.rxjava3.annotations.NonNull Map<String, String> map) {
                        params.putAll(map);
                    }

                    @Override
                    public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                        // concat 事件 完成 后调用 也就是异步获取参数拼接完成后执行
                        if (callback != null) callback.callback(params);
                    }
                });

        // flatMap + doOnNext后， 还可以拼接 其他类型Observavle
        // 这里可以直接加上调用接口的Observavle,形成链式调用,hook不符合rxjva的精髓


    }

    //    TODO 退出登陆
    public void outLogin(Activity activity) {
        TToast.show("退出登录");
        LogoutUtil.clearCache();
        Intent intent = new Intent("HomeActivity"); //启动系统自带的拨号器应用
//        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
//        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        activity.startActivity(intent);
        activity.finish();
    }

    public void saveUser(@Nonnull UserGameInfo info) {
        // cache
        ACache.get(MainApplication.getAppContext()).put(USER_GAME_INFO, info);
    }

    public UserGameInfo getUser() {
        // cache
        UserGameInfo info =
                (UserGameInfo) ACache.get(MainApplication.getAppContext()).getAsObject(USER_GAME_INFO);
        return info;
    }

    public void clearALl() {
        ACache.get(MainApplication.getAppContext()).clear();
    }

}
